<template>
    <div class="top">
        <Row>
            <Form :label-width="70" :model="queryParams" class="search-form" inline ref="searchForm">
                <Form-item label="执行器" prop="jobGroup">
                    <Select :clearable="true"  v-model="queryParams.jobGroup">
                        <Option :key="item.id" :value="item.id" v-for="item in groups">{{ item.title }}</Option>
                    </Select>
                </Form-item>
                <Form-item label="任务描述" prop="jobDesc">
                    <Input clearable placeholder="请输入任务描述" style="width: 200px" type="text"
                           v-model="queryParams.jobDesc"/>
                </Form-item>
                <Form-item label="JobHandler" prop="executorHandler">
                    <Input clearable placeholder="请输入JobHandler" style="width: 200px" type="text"
                           v-model="queryParams.executorHandler"/>
                </Form-item>
                <Form-item class="br" style="margin-left:-35px;">
                    <Button @click="getDataByFilter" icon="ios-search" type="primary">搜索</Button>
                    <Button @click="handleReset">重置</Button>
                </Form-item>
            </Form>
        </Row>
        <br>
        <Row class="operation">
            <Button @click="jobCreate" icon="md-add" type="primary">添加任务</Button>
        </Row>
        <br>
        <Row>
            <Table :columns="columns" :data="list" :loading="listLoading" border ref="multipleTable">
                <template slot="runtype" slot-scope="{ row}">
                    <span>{{row.glueType}}:{{row.executorHandler}}</span>
                </template>
                <template slot="jobStatus" slot-scope="{ row}" style="margin-right:5px">
                    <span v-if="row.triggerStatus==0">停止</span>
                    <span v-if="row.triggerStatus==1">运行</span>
                </template>
                <template slot="action" slot-scope="{ row}">
                    <Button @click="prepareTriggerOneTime(row.id)" style="margin-right:5px" type="success">执行一次</Button>
                    <Button @click="justifyIfAllow(row.triggerStatus,row.id)" style="margin-right:5px" type="warning">
                        {{row.triggerStatus==0?'启动':'停止'}}
                    </Button>
                    <Button @click="editJob(row)" size="small" style="margin-right:5px" type="primary">编辑</Button>
                    <Button @click="warnBeforeOperate(1,row.id)" size="small" style="margin-right:5px" type="error">删除
                    </Button>
                </template>
            </Table>
        </Row>
        <br>
        <Row class="page" justify="end" type="flex">
            <Page :current="queryParams.pageNum" :page-size="queryParams.pageSize" :page-size-opts="[10,20,50]"
                  :total="total" @on-change="handleCurrentChange" @on-page-size-change="handleSizeChange"
                  show-elevator show-sizer show-total size="small"></Page>
        </Row>
        <Modal :mask-closable='false' :styles="{top: '90px'}" :title="dialogType=='create' ? '新增作业' : '编辑作业'"
               :width="800"
               v-model="dialogFormVisible">
            <Form :label-width="120" :model="jobForm" :rules="rules" ref="jobForm">
                <Row>
                    <Col :span="12">
                        <Form-item label="执行器" prop="jobGroup">
                            <Select placeholder="请选择" style="width:200px" v-model="jobForm.jobGroup" >
                                <Option :key="item.id" :value="item.id" v-for="item in groups">{{ item.title }}</Option>
                            </Select>
                        </Form-item>
                        <Form-item label="路由策略" prop="executorRouteStrategy">
                            <Select placeholder="请选择" style="width:200px" v-model="jobForm.executorRouteStrategy">
                                <Option :key="item.code" :value="item.code" v-for="item in routeStrategies">{{ item.msg
                                    }}
                                </Option>
                            </Select>
                        </Form-item>
                        <Form-item label="运行模式" prop="glueType">
                            <Select placeholder="请选择" style="width:200px" v-model="jobForm.glueType">
                                <Option :key="item.code" :value="item.code" v-for="item in glueTypes">{{ item.msg }}
                                </Option>
                            </Select>
                        </Form-item>
                        <Form-item label="阻塞策略" prop="executorBlockStrategy">
                            <Select placeholder="请选择" style="width:200px" v-model="jobForm.executorBlockStrategy">
                                <Option :key="item.code" :value="item.code" v-for="item in blockStrategies">{{ item.msg}}
                                </Option>
                            </Select>
                        </Form-item>
                        <Form-item label="失败重试次数" prop="executorFailRetryCount">
                            <Input type="number" label="失败重试次数" v-model="jobForm.executorFailRetryCount"/>
                        </Form-item>

                        <Form-item label="报警邮件" prop="alarmEmail">
                            <Input label="请输入报警邮件,如果存在多个则逗号分隔" v-model="jobForm.alarmEmail"/>
                        </Form-item>
                    </Col>
                    <Col :span="12">
                        <Form-item label="任务描述" prop="jobDesc">
                            <Input label="请输入任务描述" v-model="jobForm.jobDesc"/>
                        </Form-item>
                        <Form-item label="Cron" prop="jobCron">
                            <Input label="请输入Cron" style="width: 250px"  v-model="jobForm.jobCron" disabled>
                                <Button type="primary" slot="append"  @click="cronModel=true">编辑</Button>
                            </Input>
                        </Form-item>
                        <Form-item label="JobHandler" prop="executorHandler">
                            <Input label="executorHandler" v-model="jobForm.executorHandler"/>
                        </Form-item>
                        <Form-item label="子任务ID" prop="childJobId">
                            <Input label="请输入子任务的ID,如果存在多个则逗号分隔" v-model.number="jobForm.childJobId"/>
                        </Form-item>
                        <Form-item label="超时时间" prop="executorFailRetryCount">
                            <Input type="number" label="超时时间" v-model="jobForm.executorTimeout"/>
                        </Form-item>
                        <Form-item label="负责人" prop="author">
                            <Input label="请输入负责人" v-model="jobForm.author"/>
                        </Form-item>
                    </Col>
                </Row>
                <Form-item label="任务参数" prop="executorParam">
                    <Input label="请输入任务参数" v-model="jobForm.executorParam"/>
                </Form-item>
            </Form>
            <div class="dialog-footer" slot="footer">
                <Button @click="dialogFormVisible = false">取 消</Button>
                <Button @click="addForm" type="primary" v-if="dialogType=='create'">提 交</Button>
                <Button @click="updateForm" type="primary" v-else>更 新</Button>
            </div>
        </Modal>
        <Modal :mask-closable='false' :styles="{top: '90px'}" title="cron表达式编辑" :z-index="1100"
               :width="800"
               v-model="cronModel">
            <input-cron style="width: 765px;"  v-model="jobForm.jobCron"  :hideSecond="false"></input-cron>
        </Modal>

        <Modal :mask-closable='false' :styles="{top: '90px'}" title="手动触发参数"
               :width="400"
               v-model="triggerManual">
            <Input v-model="triggerManualParam.address">
                <span slot="prepend">触发地址</span>
            </Input>
            <br>
            <Input v-model="triggerManualParam.param">
                <span slot="prepend">任务参数</span>
            </Input>
            <div class="dialog-footer" slot="footer">
                <Button @click="runTask" type="primary">执 行</Button>
            </div>
        </Modal>
    </div>
</template>

<script>
    import {
        create,
        getJobPageList,
        start,
        stop,
        jobTrigger,
        remove,
        update
    } from "@/projects/basic/api/jobadmin/jobs";
    import { listAllGroup } from "@/projects/basic/api/jobadmin/group";
    import {deepClone} from "@/libs/utils/ObjectClone";
    import inputCron from "_c/cron/index";
    import CronValidator from '_c/cron/validator'
    export default {
        components:{
            inputCron
        },
        data() {
            return {
                dialogType: '',
                cronModel:false,
                triggerManual:false,
                columns: [
                    {
                        title: "任务ID",
                        key: 'id',
                        width: 80,
                        align: "center"
                    },
                    {
                        title: "任务描述",
                        key: 'jobDesc',
                        tooltip: true,
                        align: "center"
                    },
                    {
                        title: "运行模式",
                        tooltip: true,
                        align: "center",
                        slot: 'runtype'
                    },
                    {
                        title: "Cron",
                        key: 'jobCron',
                        tooltip: true,
                        align: "center"
                    },
                    {
                        title: "状态",
                        tooltip: true,
                        align: "center",
                        slot: 'jobStatus'
                    },
                    {
                        title: "操作",
                        width: 260,
                        align: "center",
                        slot: 'action'
                    },
                ],
                groups: [],
                routeStrategies: [
                    {
                        code: 'FIRST',
                        msg: '第一个'
                    },
                    {
                        code: 'LAST',
                        msg: '最后一个'
                    }, {
                        code: 'ROUND',
                        msg: '轮询'
                    }, {
                        code: 'RANDOM',
                        msg: '随机'
                    }, {
                        code: 'CONSISTENT_HASH',
                        msg: '一致性HASH'
                    }, {
                        code: 'LEAST_FREQUENTLY_USED',
                        msg: '最不经常使用'
                    }, {
                        code: 'LEAST_RECENTLY_USED',
                        msg: '最近最久未使用'
                    }, {
                        code: 'FAILOVER',
                        msg: '故障转移'
                    }, {
                        code: 'BUSYOVER',
                        msg: '忙碌转移'
                    }, {
                        code: 'SHARDING_BROADCAST',
                        msg: '分片广播'
                    }
                ],
                glueTypes: [
                    {
                        code: 'BEAN',
                        msg: 'BEAN'
                    },
                    // {
                    //     code: 'GLUE_GROOVY',
                    //     msg: 'GLUE_GROOVY'
                    // },
                    // {
                    //     code: 'GLUE_SHELL',
                    //     msg: 'GLUE(Shell)'
                    // },
                    // {
                    //     code: 'GLUE_PYTHON',
                    //     msg: 'GLUE_PYTHON'
                    // }, {
                    //     code: 'GLUE_NODEJS',
                    //     msg: 'GLUE(Nodejs)'
                    // }, {
                    //     code: 'GLUE_POWERSHELL',
                    //     msg: 'GLUE(PowerShell)'
                    // }
                ],
                blockStrategies: [
                    {
                        code: 'SERIAL_EXECUTION',
                        msg: '单机串行'
                    },
                    {
                        code: 'DISCARD_LATER',
                        msg: '丢弃后续调度'
                    },
                    {
                        code: 'COVER_EARLY',
                        msg: '覆盖之前调度'
                    }
                ],
                total: 0,
                list: [],
                listLoading: false,
                dialogFormVisible: false,
                queryParams: {
                    jobGroup: null,
                    jobDesc: '',
                    executorHandler: '',
                    pageNum: 1,
                    pageSize: 10,
                },
                jobForm: {
                    id: null,
                    jobGroup: '',
                    executorRouteStrategy: 'FIRST',
                    glueType: 'BEAN',
                    executorParam: '',
                    executorBlockStrategy: 'SERIAL_EXECUTION',
                    author: 'admin',
                    jobDesc: '',
                    jobCron: '',
                    executorHandler: '',
                    childJobId: '',
                    executorFailRetryCount: 0,
                    executorTimeout:0,
                    alarmEmail: ''
                },
                rules: {
                    jobGroup: [{required: true, message: '请选择执行器', trigger: 'change',type:'number'}],
                    executorRouteStrategy: [{required: true, message: '请选择路由策略', trigger: 'change'}],
                    executorHandler: [{required: true, message: '请输入执行器BEAN名称', trigger: 'blur'}],
                    glueType: [{required: true, message: '请选择运行模式', trigger: 'change'}],
                    author: [{required: true, message: '请输入负责人', trigger: 'blur'}],
                    jobDesc: [{required: true, message: '请输入任务描述', trigger: 'blur'}],
                    jobCron: [{required: true, message: '请输入Cron表达式', trigger: 'blur'},CronValidator],
                    alarmEmail: [{required: false, message: '请输入邮箱地址', trigger: 'blur'}, {
                        type: 'email',
                        message: '请输入正确的邮箱地址',
                        trigger: ['blur', 'change']
                    }],
                    executorBlockStrategy: [{required: true, message: '请选择阻塞策略', trigger: 'change'}],
                },
                operateJobId: null,
                pageBoolean: {
                    delColor: 'primary',
                    delText: '批量删除',
                    addColor: 'success',
                    addText: '添加作业'
                },
                triggerManualParam:{
                    id:0,
                    address:'',
                    param:''
                },
                operateText: ['执行', '暂停', '删除'],
            };
        },
        created() {
            listAllGroup().then(res => {
                if (res.code = '0000') {
                    this.groups = res.data;
                }
            }).catch(() => {
                this.$Message.error("获取执行器信息失败");
            });
            this.getJobsList();
        },
        methods: {
            handleReset() {
                this.$refs.searchForm.resetFields();
                this.getJobsList();
            },
            addForm() {
                this.$refs['jobForm'].validate((valid) => {
                    if (valid) {
                        create(this.jobForm).then(res => {
                            if (res.code === '0000') {
                                this.dialogFormVisible = false
                                this.$Message.success('新增成功');
                                this.getJobsList()
                            } else {
                                this.$Message.error(res.msg)
                            }
                        }).catch(function (err) {
                            console.log(err.message)
                        })
                    } else {
                        return false;
                    }
                });
            },
            updateForm() {
                this.$refs['jobForm'].validate((valid) => {
                    if (valid) {
                        update(this.jobForm).then(res => {
                            if (res.code === '0000') {
                                this.dialogFormVisible = false
                                this.$Message.success('更新成功');
                                this.getJobsList()
                            } else {
                                this.$Message.error(res.msg);
                            }
                        }).catch(function (err) {
                            console.log(err.message)
                        })
                    } else {
                        return false;
                    }
                });
            },
            getJobsList() {
                getJobPageList(this.queryParams).then(res => {
                    const {code, msg, data: {total, records}} = res
                    if (code === '0000') {
                        this.total = total
                        this.list = records
                    } else {
                        this.$Message.error(msg)
                    }
                    this.listLoading = false
                }).catch(reject => {
                    this.listLoading = false;
                });
            },
            getDataByFilter() {
                this.queryParams.pageNum = 1
                this.getJobsList()
            },
            jobCreate() {
                this.$refs.jobForm.resetFields();
                this.jobForm.executorRouteStrategy= 'FIRST';
                this.jobForm.glueType='BEAN';
                this.jobForm.executorParam='';
                this.jobForm.author='admin';
                this.jobForm.executorBlockStrategy= 'SERIAL_EXECUTION';
                this.dialogFormVisible = true;
                this.dialogType = 'create'
            },
            warnBeforeOperate(type, id) {
                this.$Modal.confirm({
                    title: "确认",
                    content: '确认'+this.operateText[type] + '该作业？',
                    onOk: () => {
                        if (type === 0) {
                            this.exeJob(id)
                        } else if (type === 1) {
                            this.deleteJob(id)
                        }
                    }
                });
            },
            runTask(){
                jobTrigger(this.triggerManualParam).then(res => {
                    if (res.code == '0000') {
                        this.$Message.success('触发成功');
                        this.triggerManualParam.address='';
                        this.triggerManualParam.param = '';
                        this.triggerManualParam.id = -1;
                        this.triggerManual = false;
                    } else {
                        this.$Message.error(res.msg);
                    }
                }).catch(function (err) {
                    this.$Message.error(err)
                })
            },
            prepareTriggerOneTime(id){
                this.triggerManualParam.id = id;
                this.triggerManualParam.address='';
                this.triggerManualParam.param = '';
                this.triggerManual = true;
            },
            justifyIfAllow(status, id) {
                this.warnBeforePauseAndBack(status, id)
            },
            warnBeforePauseAndBack(status, id) {
                let statusDesc = status === 0 ? '启动' : '停止'
                this.$Modal.confirm({
                    title: "确认",
                    content: '确认'+statusDesc + '该作业？',
                    onOk: () => {
                        if (status === 0) {
                            this.start(id)
                        } else if (status === 1) {
                            this.stop(id)
                        }
                    }
                });
            },
            exeJob(id) {
                jobTrigger(id).then(res => {
                    if (res.code == '0000') {
                        this.$Message.success('触发成功');
                        this.getJobsList()
                    } else {
                        this.$Message.error(res.msg);
                    }
                }).catch(function (err) {
                    this.$Message.error(err)
                })
            },
            stop(id) {
                stop(id).then(res => {
                    if (res.code === '0000') {
                        this.$Message.success('停止成功');
                        this.getJobsList()
                    } else {
                        this.$Message.error(res.msg);
                    }
                }).catch(function (err) {
                })
            },
            start(id) {
                start(id).then(res => {
                    if (res.code === '0000') {
                        this.$Message.success('启动成功');
                        this.getJobsList()
                    } else {
                        this.$Message.error(res.msg);
                    }
                }).catch(function (err) {
                })
            },
            deleteJob(id) {
                remove(id).then(res => {
                    if (res.code == '0000') {
                        this.$Message.success('删除成功');
                        this.getJobsList()
                    } else {
                        this.$Message.error(res.msg);
                    }
                }).catch(function (err) {
                })
            },
            editJob(row) {
                this.$refs.jobForm.resetFields();
                this.jobForm = deepClone(row);
                this.dialogFormVisible = true
                this.operateJobId = row.id
                this.dialogType = 'update'
            },
            handleSizeChange(val) {
                this.queryParams.pageSize = val
                this.getJobsList()
            },
            handleCurrentChange(val) {
                this.queryParams.pageNum = val
                this.getJobsList()
            }
        },
        computed: {}
    };
</script>
